/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { ArkFile, AstTreeUtils, ts } from "arkanalyzer";
import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
import { BaseChecker, BaseMetaData } from '../BaseChecker';
import { Rule, MatcherTypes, MatcherCallback, FileMatcher, Utils } from '../../Index';
import { RuleListUtil } from "../../utils/common/DefectsList";
import { Defects, IssueReport } from '../../model/Defects';

const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoUselessBackreferenceCheck');

type MessageIds = 'nested'
    | 'forward'
    | 'backward'
    | 'disjunctive'
    | 'intoNegativeLookaround';

interface MessageInfo {
    nested: string;
    forward: string;
    backward: string;
    disjunctive: string;
    intoNegativeLookaround: string;
}

// 储存反向引用的信息
interface BackReferenceInfo {
    backReference: string;
    groupContent: string;
}

// 定义捕获组信息的接口
interface CaptureGroupInfo {
    startIndex: number; // 捕获组在正则表达式中的起始索引
    endIndex: number;   // 捕获组在正则表达式中的结束索引
    content: string;    // 捕获组的内容
    fullMatch: string;  // 捕获组的完整匹配（包括括号）
    name?: string;      // 命名捕获组的名称
    number: number;     // 捕获组的编号
    parentAlternative?: any; // 记录捕获组所在的可选分支
}

interface CommentInfo {
    line: number;
    startCol: number;
    message: string;
    filePath?: string;
}

export class NoUselessBackreferenceCheck implements BaseChecker {
    private messageId: MessageIds = 'nested';
    private backReferenceInfo: BackReferenceInfo = {
        backReference: '',
        groupContent: '',
    };
    private get messages(): MessageInfo {
        return {
            nested: `Backreference '${this.backReferenceInfo.backReference}' will be ignored. It references group '(${this.backReferenceInfo.groupContent})' from within that group.`,
            forward: `Backreference '${this.backReferenceInfo.backReference}' will be ignored. It references group '(${this.backReferenceInfo.groupContent})' which appears later in the pattern.`,
            backward: `Backreference '${this.backReferenceInfo.backReference}' will be ignored. It references group '(${this.backReferenceInfo.groupContent})' which appears before in the same lookbehind.`,
            disjunctive: `Backreference '${this.backReferenceInfo.backReference}' will be ignored. It references group '(${this.backReferenceInfo.groupContent})' which is in another alternative.`,
            intoNegativeLookaround: `Backreference '${this.backReferenceInfo.backReference}' will be ignored. It references group '(${this.backReferenceInfo.groupContent})' which is in a negative lookaround.`,
        }
    };
    public rule: Rule;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    private issueMap: Map<string, IssueReport> = new Map();
    private filePath: string = '';

    public metaData: BaseMetaData = {
        severity: 2,
        ruleDocPath: 'docs/no-useless-backreference-check.md',
        description: 'Disallow useless backreferences in regular expressions.',
    };

    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE,
    };

    public registerMatchers(): MatcherCallback[] {
        const fileMatcherCb: MatcherCallback = {
            matcher: this.fileMatcher,
            callback: this.check,
        };

        return [fileMatcherCb];
    }

    /**
     * 
     * 在 JavaScript 中，使用斜杠 / 定义正则表达式时，反向引用直接用 \n 表示；
     * 使用 RegExp 构造函数时，由于字符串中的反斜杠需要转义，所以要写成 \\n。
     * 在替换字符串中，使用 $n 来引用捕获组。
     */

    public check = (target: ArkFile) => {
        try {
            const code = target.getCode();
            if (!code) {
                return;
            }
            this.filePath = target.getFilePath();
            const sourceFile = AstTreeUtils.getASTNode(target.getName(), code);

            this.issueMap.clear();

            // 遍历 AST
            this.visitNode(sourceFile, sourceFile);

            this.reportSortedIssues();
        } catch (error) {
            logger.error(`Error occurred while checking file: ${target.getFilePath()}, Error: ${error}`);
        }
    };

    private visitNode(node: ts.Node, sourceFile: ts.SourceFile): void {
        // 检查正则字面量
        if (ts.isRegularExpressionLiteral(node)) {
            this.analyzeRegexPattern(node.text, node, sourceFile);
            return;
        }

        // 统一处理 RegExp 构造函数调用和 new 表达式
        if ((ts.isNewExpression(node) || ts.isCallExpression(node)) && node.arguments && node.arguments?.length > 0) {
            // 首先检查是否是全局 RegExp
            if (this.isGlobalRegExp(node.expression)) {
                // 获取第一个参数
                const pattern = this.extractRegExpPattern(node.arguments[0]);
                if (pattern) {
                    this.analyzeRegexPattern(pattern, node, sourceFile);
                }
            }
        }

        // 递归遍历子节点
        ts.forEachChild(node, child => this.visitNode(child, sourceFile));
    }

    private isGlobalRegExp(expression: ts.Expression): boolean {
        // 检查是否是标识符
        if (!ts.isIdentifier(expression)) {
            return false;
        }

        if (expression.text === 'RegExp') {
            // 获取当前作用域
            let current: ts.Node = expression;
            let foundBlock = false;

            while (current) {
                // 检查块级作用域
                if (ts.isBlock(current) || ts.isSourceFile(current)) {
                    foundBlock = true;
                    // 在当前块中查找变量声明
                    const checkNode = (node: ts.Node): boolean => {
                        if (ts.isVariableDeclaration(node) &&
                            ts.isIdentifier(node.name) &&
                            node.name.text === 'RegExp') {
                            // 找到了局部声明的 RegExp
                            return true;
                        }
                        return false;
                    };

                    // 遍历当前块中的所有语句
                    const checkStatements = (statements: ts.NodeArray<ts.Statement>): boolean => {
                        for (const stmt of statements) {
                            if (ts.isVariableStatement(stmt)) {
                                for (const decl of stmt.declarationList.declarations) {
                                    if (checkNode(decl)) {
                                        return true;
                                    }
                                }
                            }
                        }
                        return false;
                    };

                    if (ts.isBlock(current) && checkStatements(current.statements)) {
                        return false;
                    }

                    if (ts.isSourceFile(current) && checkStatements(current.statements)) {
                        return false;
                    }
                }

                // 检查函数声明和参数
                if (ts.isFunctionDeclaration(current) ||
                    ts.isFunctionExpression(current) ||
                    ts.isArrowFunction(current)) {
                    for (const param of current.parameters) {
                        if (ts.isIdentifier(param.name) && param.name.text === 'RegExp') {
                            return false;
                        }
                    }
                }

                current = current.parent;
            }

            // 如果没有找到局部声明，且在全局作用域中，则认为是全局 RegExp
            return foundBlock;
        }

        // 处理别名情况
        const sourceFile = expression.getSourceFile();
        let currentNode: ts.Node = expression;

        while (currentNode) {
            if (ts.isSourceFile(currentNode)) {
                // 在全局作用域中查找别名声明
                for (const statement of sourceFile.statements) {
                    if (ts.isVariableStatement(statement)) {
                        for (const decl of statement.declarationList.declarations) {
                            if (ts.isIdentifier(decl.name) &&
                                decl.name.text === expression.text &&
                                decl.initializer &&
                                ts.isIdentifier(decl.initializer) &&
                                decl.initializer.text === 'RegExp') {
                                // 确保全局 RegExp 没有被重定义
                                return this.isGlobalRegExp(decl.initializer);
                            }
                        }
                    }
                }
            }
            currentNode = currentNode.parent;
        }

        return false;
    }

    private getVariableDeclarations(node: ts.Node): (ts.VariableDeclaration | ts.ParameterDeclaration)[] {
        const declarations: (ts.VariableDeclaration | ts.ParameterDeclaration)[] = [];

        const visit = (n: ts.Node) => {
            if (ts.isVariableDeclaration(n) || ts.isParameter(n)) {
                declarations.push(n);
            }
            ts.forEachChild(n, visit);
        };

        ts.forEachChild(node, visit);
        return declarations;
    }

    private extractRegExpPattern(arg: ts.Expression): string | null {
        // 直接的字符串字面量
        if (ts.isStringLiteral(arg)) {
            return arg.text;
        }

        // 字符串拼接
        if (ts.isBinaryExpression(arg) && arg.operatorToken.kind === ts.SyntaxKind.PlusToken) {
            return this.evaluateStringConcatenation(arg);
        }

        return null;
    }

    private evaluateTemplate(node: ts.TemplateExpression | ts.NoSubstitutionTemplateLiteral): string | null {
        if (ts.isNoSubstitutionTemplateLiteral(node)) {
            return node.text;
        }

        // 对于包含插值的模板字符串，只处理头部文本
        return node.head.text;
    }

    private getNodeType(node: ts.Node): boolean {
        try {
            // 检查是否是 RegExp 构造函数调用
            if ((ts.isNewExpression(node) || ts.isCallExpression(node)) &&
                node.expression && ts.isIdentifier(node.expression)) {

                // 检查调用的是否是 RegExp
                if (node.expression.text === 'RegExp') {
                    return true;
                }

                // 检查变量名是否包含 RegExp 相关标识
                const name = node.expression.text.toLowerCase();
                return name.includes('regexp') || name.includes('regex');
            }

            // 检查变量声明
            if (ts.isVariableDeclaration(node) && node.initializer) {
                if (ts.isNewExpression(node.initializer) || ts.isCallExpression(node.initializer)) {
                    return this.getNodeType(node.initializer);
                }
            }

            // 检查属性访问
            if (ts.isPropertyAccessExpression(node)) {
                const propName = node.name.text.toLowerCase();
                return propName.includes('regexp') || propName.includes('regex');
            }

            return false;
        } catch (error) {
            return false;
        }
    }
    
    private isGlobalRegExpSymbol(node: ts.Identifier): boolean {
        try {
            // 检查标识符名称
            const name = node.text.toLowerCase();
            if (name === 'regexp' || name.includes('regexp') || name.includes('regex')) {
                return true;
            }

            // 检查父节点
            const parent = node.parent;
            if (parent) {
                // 检查是否在 new 表达式或函数调用中
                if (ts.isNewExpression(parent) || ts.isCallExpression(parent)) {
                    return true;
                }

                // 检查变量声明
                if (ts.isVariableDeclaration(parent)) {
                    const varName = parent.name.getText().toLowerCase();
                    return varName.includes('regexp') || varName.includes('regex');
                }

                // 检查属性赋值
                if (ts.isPropertyAssignment(parent) || ts.isPropertyDeclaration(parent)) {
                    const propName = parent.name.getText().toLowerCase();
                    return propName.includes('regexp') || propName.includes('regex');
                }
            }

            return false;
        } catch (error) {
            return false;
        }
    }

    private isRegExpConstructor(node: ts.Node): boolean {
        try {
            // 检查是否是标识符
            if (ts.isIdentifier(node)) {
                const name = node.text.toLowerCase();
                return name === 'regexp' || name.includes('regexp') || name.includes('regex');
            }

            // 检查是否是 new 表达式
            if (ts.isNewExpression(node)) {
                const expression = node.expression;
                if (ts.isIdentifier(expression)) {
                    return this.isGlobalRegExpSymbol(expression);
                }
            }

            // 检查是否是函数调用
            if (ts.isCallExpression(node)) {
                const expression = node.expression;
                if (ts.isIdentifier(expression)) {
                    return this.isGlobalRegExpSymbol(expression);
                }
            }

            // 检查变量声明
            if (ts.isVariableDeclaration(node)) {
                // 检查变量名
                const name = node.name.getText().toLowerCase();
                if (name.includes('regexp') || name.includes('regex')) {
                    return true;
                }

                // 检查初始化表达式
                if (node.initializer) {
                    if (ts.isNewExpression(node.initializer) || ts.isCallExpression(node.initializer)) {
                        return this.isRegExpConstructor(node.initializer);
                    }
                }
            }

            return false;
        } catch (error) {
            return false;
        }
    }

    private evaluateStringConcatenation(node: ts.BinaryExpression): string | null {
        try {
            let result = '';

            // 递归处理左侧
            if (ts.isBinaryExpression(node.left)) {
                const leftResult = this.evaluateStringConcatenation(node.left);
                // 如果左侧包含未知变量，返回 null
                if (leftResult === null) return null;
                result += leftResult;
            } else if (ts.isStringLiteral(node.left)) {
                result += node.left.text;
            } else if (ts.isIdentifier(node.left)) {
                // 处理标识符
                const value = this.getIdentifierValue(node.left);
                if (value === null) return null;
                result += value;
            } else {
                // 如果左侧不是字符串字面量或有效的拼接表达式，返回 null
                return null;
            }

            // 处理右侧
            if (ts.isBinaryExpression(node.right)) {
                const rightResult = this.evaluateStringConcatenation(node.right);
                // 如果右侧包含未知变量，返回 null
                if (rightResult === null) return null;
                result += rightResult;
            } else if (ts.isStringLiteral(node.right)) {
                result += node.right.text;
            } else if (ts.isIdentifier(node.right)) {
                // 处理标识符
                const value = this.getIdentifierValue(node.right);
                if (value === null) return null;
                result += value;
            } else {
                // 如果右侧不是字符串字面量或有效的拼接表达式，返回 null
                return null;
            }

            return result;
        } catch (error) {
            return null;
        }
    }

    private getIdentifierValue(node: ts.Identifier): string | null {
        try {
            // 查找标识符的声明
            const symbol = node.getText();
            const sourceFile = node.getSourceFile();

            // 在源文件中查找变量声明
            let value: string | null = null;
            ts.forEachChild(sourceFile, (child) => {
                if (ts.isVariableStatement(child)) {
                    child.declarationList.declarations.forEach((declaration) => {
                        if (ts.isIdentifier(declaration.name) &&
                            declaration.name.text === symbol &&
                            declaration.initializer &&
                            ts.isStringLiteral(declaration.initializer)) {
                            value = declaration.initializer.text;
                        }
                    });
                }
            });

            return value;
        } catch (error) {
            return null;
        }
    }

    // 查找正则表达式中的所有捕获组
    findCaptureGroups(pattern: string): CaptureGroupInfo[] {
        const groups: CaptureGroupInfo[] = [];
        let groupNumber = 1;
        const stack: number[] = [];

        for (let i = 0; i < pattern.length; i++) {
            if (pattern[i] === '(') {
                // 检查是否是转义的左括号
                if (i > 0 && pattern[i - 1] === '\\') {
                    continue;
                }
                // 检查是否是命名捕获组
                if (i + 2 < pattern.length && pattern[i + 1] === '?' && pattern[i + 2] === '<') {
                    const endNameIndex = pattern.indexOf('>', i + 3);
                    if (endNameIndex !== -1) {
                        const name = pattern.slice(i + 3, endNameIndex);
                        stack.push(i);
                        continue;
                    }
                }
                // 检查是否是非捕获组或环视
                if (i + 2 < pattern.length && pattern[i + 1] === '?' && [':', '=', '!', '<'].includes(pattern[i + 2])) {
                    continue;
                }
                // 普通捕获组
                stack.push(i);
            } else if (pattern[i] === ')') {
                // 检查是否是转义的右括号
                if (i > 0 && pattern[i - 1] === '\\') {
                    continue;
                }
                if (stack.length > 0) {
                    const startIndex = stack.pop()!;
                    const content = pattern.slice(startIndex + 1, i);
                    const fullMatch = pattern.slice(startIndex, i + 1);
                    const namedGroupMatch = pattern.slice(startIndex).match(/^\(\?<([^>]+)>/);
                    const name = namedGroupMatch ? namedGroupMatch[1] : undefined;
                    groups.push({
                        startIndex,
                        endIndex: i + 1,
                        content,
                        fullMatch,
                        name,
                        number: groupNumber++
                    });
                }
            }
        }

        return groups;
    }

    private findClosingParenthesis(pattern: string, start: number): { endIndex: number, content: string } {
        let count = 1;
        let i = start + 1;

        while (count > 0 && i < pattern.length) {
            if (pattern[i] === '(' && pattern[i - 1] !== '\\') {
                count++;
            } else if (pattern[i] === ')' && pattern[i - 1] !== '\\') {
                count--;
            }
            i++;
        }

        const result = {
            endIndex: i,
            content: pattern.slice(start + 1, i - 1)
        };
        return result;
    }

    private findBackReferences(pattern: string): Array<{ index: number, value: string, isNamed: boolean }> {
        const result: Array<{ index: number, value: string, isNamed: boolean }> = [];
        let inCharClass = false;

        for (let i = 0; i < pattern.length; i++) {
            const char = pattern[i];

            // 处理字符类
            if (char === '[' && !this.isEscaped(pattern, i)) {
                inCharClass = true;
                continue;
            }
            if (char === ']' && !this.isEscaped(pattern, i)) {
                inCharClass = false;
                continue;
            }

            // 在字符类内的反斜杠序列不作为反向引用处理
            if (inCharClass) {
                continue;
            }

            // 原有的反向引用检测逻辑
            if (char === '\\' && !this.isEscaped(pattern, i)) {
                const next = pattern[i + 1];
                if (next === 'k') {
                    // 命名反向引用 \k<name>
                    const match = pattern.slice(i).match(/^\\k<([^>]+)>/);
                    if (match) {
                        result.push({
                            index: i,
                            value: match[0],
                            isNamed: true
                        });
                        i += match[0].length - 1;
                    }
                } else if (/\d/.test(next)) {
                    // 数字反向引用 \1, \2, etc.
                    const match = pattern.slice(i).match(/^\\(\d+)/);
                    if (match) {
                        result.push({
                            index: i,
                            value: match[0],
                            isNamed: false
                        });
                        i += match[0].length - 1;
                    }
                }
            }
        }

        return result;
    }

    private isEscaped(str: string, index: number): boolean {
        let count = 0;
        let i = index - 1;
        while (i >= 0 && str[i] === '\\') {
            count++;
            i--;
        }
        return count % 2 === 1;
    }

    private isForwardReference(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        // 先检查是否在先行断言中
        let currentIndex = 0;
        while (currentIndex < pattern.length) {
            const lookAheadIndex = pattern.indexOf('(?', currentIndex);
            if (lookAheadIndex === -1) break;

            // 检查是否是先行断言（正向或负向）
            if (pattern[lookAheadIndex + 2] === '=' || pattern[lookAheadIndex + 2] === '!') {
                const { endIndex } = this.findClosingParenthesis(pattern, lookAheadIndex);

                // 如果引用和组都在这个先行断言内
                if (refIndex > lookAheadIndex && refIndex < endIndex &&
                    group.startIndex > lookAheadIndex && group.endIndex < endIndex) {

                    // 计算相对位置
                    const relativeRefIndex = refIndex - lookAheadIndex;
                    const relativeGroupStart = group.startIndex - lookAheadIndex;

                    // 在先行断言内，如果引用在组之前，就是前向引用
                    if (relativeRefIndex < relativeGroupStart) {
                        // 检查是否在后行断言内
                        const isInLookbehind = this.isInLookbehind(lookAheadIndex, pattern);
                        // 如果不在后行断言内，才报告为前向引用
                        return !isInLookbehind;
                    }
                }
            }
            currentIndex = lookAheadIndex + 1;
        }

        // 2. 对于不在先行断言内的情况
        // 如果引用在组之前，且不在后行断言内，就是前向引用
        if (refIndex < group.startIndex && !this.isInAnyLookbehind(refIndex, pattern)) {
            // 检查是否在非捕获组中
            const nonCapturingGroup = this.findEnclosingNonCapturingGroup(refIndex, pattern);
            if (nonCapturingGroup !== -1) {
                // 如果组也在同一个非捕获组内，使用相对位置判断
                if (group.startIndex > nonCapturingGroup) {
                    return true;
                }
            } else {
                // 不在非捕获组内，使用全局位置判断
                return true;
            }
        }

        return false;
    }

    private findEnclosingNonCapturingGroup(index: number, pattern: string): number {
        let currentIndex = 0;
        while (currentIndex < index) {
            const groupIndex = pattern.indexOf('(?:', currentIndex);
            if (groupIndex === -1 || groupIndex > index) break;

            const { endIndex } = this.findClosingParenthesis(pattern, groupIndex);
            if (index > groupIndex && index < endIndex) {
                return groupIndex;
            }
            currentIndex = groupIndex + 1;
        }
        return -1;
    }

    private isInLookbehind(index: number, pattern: string): boolean {
        let currentIndex = 0;
        while (currentIndex < index) {
            const lookbehindIndex = pattern.indexOf('(?<', currentIndex);
            if (lookbehindIndex === -1 || lookbehindIndex > index) break;

            if (pattern[lookbehindIndex + 3] === '=' || pattern[lookbehindIndex + 3] === '!') {
                const { endIndex } = this.findClosingParenthesis(pattern, lookbehindIndex);
                if (index > lookbehindIndex && index < endIndex) {
                    return true;
                }
            }
            currentIndex = lookbehindIndex + 1;
        }
        return false;
    }

    private isInAnyLookbehind(index: number, pattern: string): boolean {
        return this.isInLookbehind(index, pattern);
    }

    private isBackwardReferenceInLookbehind(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        // 查找所有后行断言的位置
        const lookbehinds = Array.from(pattern.matchAll(/\(\?<[=!]/g));

        for (const lookbehind of lookbehinds) {
            const lookbehindStart = lookbehind.index!;
            const { endIndex } = this.findClosingParenthesis(pattern, lookbehindStart);

            // 如果引用和组都在同一个后行断言内
            if (refIndex > lookbehindStart && refIndex < endIndex) {
                if (group.startIndex > lookbehindStart && group.startIndex < endIndex) {
                    // 且引用在组之后
                    if (refIndex > group.startIndex && !this.isInSameLookahead(group, refIndex, pattern.slice(lookbehindStart, endIndex))) {
                        return true;
                    }
                }

                // 如果组也在同一个后行断言内，则是合法的
                if (group.startIndex > lookbehindStart && group.endIndex < endIndex) {
                    return false;
                }
                // 如果组在后行断言外，且引用在组之前，则是非法的
                if (refIndex < group.startIndex) {
                    return true;
                }
            }
        }
        return false;
    }

    // 检查是否在同一个先行断言内
    private isInSameLookahead(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        const lookAheads = Array.from(pattern.matchAll(/\(\?=/g));

        for (const lookAhead of lookAheads) {
            const start = lookAhead.index!;
            const { endIndex } = this.findClosingParenthesis(pattern, start);

            // 如果组和引用都在这个先行断言内
            if (group.startIndex >= start && group.endIndex <= endIndex &&
                refIndex >= start && refIndex <= endIndex) {
                return true;
            }
        }

        return false;
    }

    private hasRegExpSyntaxError(pattern: string, flags: string): boolean {
        try {
            // 尝试创建正则表达式对象
            if (flags) {
                new RegExp(pattern, flags);
            } else {
                new RegExp(pattern);
            }
            return false;
        } catch (e) {
            return true;
        }
    }

    private getRegExpFlags(node: ts.Node): string {
        if (ts.isNewExpression(node) || ts.isCallExpression(node)) {
            if (node.arguments && node.arguments.length > 0) {
                // 检查第二个参数是否存在且是字符串字面量
                const flagsArg = node.arguments[1];
                if (flagsArg) {
                    if (ts.isStringLiteral(flagsArg)) {
                        return flagsArg.text;
                    } else if (ts.isIdentifier(flagsArg)) {
                        // 对于标识符，我们只能获取其字面值
                        const flagsName = flagsArg.getText();
                        // 简单处理一些常见的标志组合
                        if (flagsName === 'flags' || flagsName.includes('u')) {
                            return 'u';  // 保守处理，假设包含 'u' 标志
                        }
                    }
                }
            }
        }
        return '';
    }

    private analyzeRegexPattern(pattern: string, node: ts.Node, sourceFile: ts.SourceFile): void {
        // 首先检查正则表达式是否有语法错误
        if (this.hasRegExpSyntaxError(pattern, this.getRegExpFlags(node))) {
            return;
        }

        const captureGroups = this.findCaptureGroups(pattern);
        const backReferences = this.findBackReferences(pattern);

        for (const backRef of backReferences) {
            const { index, value, isNamed } = backRef;
            const refNumber = isNamed ? -1 : parseInt(value.slice(1));
            const refName = isNamed ? value.slice(3, -1) : '';

            const referencedGroup = isNamed
                ? captureGroups.find(g => g.name === refName)
                : captureGroups[refNumber - 1];

            // 如果引用的组不存在，说明可能是前向引用
            if (!referencedGroup) {
                continue;
            }

            // 检查是否在组内
            const isInGroup = index > referencedGroup.startIndex && index <= referencedGroup.endIndex;

            // 检查是否引用了自身所在的组
            const isCircular = isInGroup && (
                (refNumber > 0 && refNumber === referencedGroup.number) || // 数字引用
                (refNumber === -1 && referencedGroup.name === refName) // 命名引用
            );

            if (isCircular) {
                // 检查在引用点之前是否有有效的捕获组
                const subPattern = pattern.slice(referencedGroup.startIndex, index);
                const groupsBeforeRef = this.findCaptureGroups(subPattern);

                // 如果引用点之前没有有效的捕获组，这是无效的嵌套引用
                if (groupsBeforeRef.length === 0) {
                    this.messageId = 'nested';
                    this.reportIssue(node, sourceFile, referencedGroup, value, index);
                    continue;
                }
            }

            // 检查后行断言中的反向引用 (backward)
            if (this.isBackwardReferenceInLookbehind(referencedGroup, index, pattern)) {
                this.messageId = 'backward';
                this.reportIssue(node, sourceFile, referencedGroup, value, index);
            }

            // 检查前向引用 (forward)
            if (this.isForwardReference(referencedGroup, index, pattern)) {
                this.messageId = 'forward';
                this.reportIssue(node, sourceFile, referencedGroup, value, index);
            }

            // 检查不同分支中的引用 (disjunctive)
            if (this.isInDifferentAlternative(referencedGroup, index, pattern) ||
                this.isInDifferentOther(referencedGroup, index, pattern)) {
                this.messageId = 'disjunctive';
                this.reportIssue(node, sourceFile, referencedGroup, value, index);
            }

            // 检查是否在负向环视中
            if (!this.isInSameLookaround(referencedGroup, index, pattern) &&
                this.isInNegativeLookaround(referencedGroup, index, pattern)) {
                this.messageId = 'intoNegativeLookaround';
                this.reportIssue(node, sourceFile, referencedGroup, value, index);
                continue;
            }
        }
    }

    // 检查是否在同一个环视结构内（包括肯定/否定的前/后行断言）
    private isInSameLookaround(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        const lookarounds = Array.from(pattern.matchAll(/\(\?[<]?[=!]/g));

        for (const lookaround of lookarounds) {
            const start = lookaround.index!;
            const { endIndex } = this.findClosingParenthesis(pattern, start);

            // 如果引用在这个环视内
            if (refIndex > start && refIndex < endIndex) {
                // 检查组是否也在同一个环视内
                if (group.startIndex > start && group.endIndex < endIndex) {
                    return true;
                }

                // 检查嵌套的环视
                const subPattern = pattern.slice(start, endIndex);
                const nestedLookarounds = Array.from(subPattern.matchAll(/\(\?[<]?[=!]/g));

                for (const nested of nestedLookarounds) {
                    if (nested.index === 0) continue; // 跳过当前环视本身

                    const nestedStart = start + nested.index!;
                    const { endIndex: nestedEnd } = this.findClosingParenthesis(pattern, nestedStart);

                    // 如果组和引用都在嵌套的环视内，这是有效的
                    const relativeRefIndex = refIndex - start;
                    const relativeGroupStart = group.startIndex - start;
                    const relativeGroupEnd = group.endIndex - start;

                    if (nested.index && relativeRefIndex > nested.index && relativeRefIndex < (nestedEnd - start) &&
                        relativeGroupStart > nested.index && relativeGroupEnd < (nestedEnd - start)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private isInDifferentAlternative(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        let depth = 0;
        let alternativeStart = 0;
        let topLevelAlternatives: { start: number; end: number }[] = [];

        // 第一次遍历：收集顶层分支的范围
        for (let i = 0; i < pattern.length; i++) {
            const char = pattern[i];

            if (char === '(' && !this.isEscaped(pattern, i)) {
                depth++;
            } else if (char === ')' && !this.isEscaped(pattern, i)) {
                depth--;
            } else if (char === '|' && !this.isEscaped(pattern, i) && depth === 0) {
                // 记录每个顶层分支的结束位置
                topLevelAlternatives.push({
                    start: alternativeStart,
                    end: i
                });
                alternativeStart = i + 1;
            }
        }
        // 添加最后一个分支
        topLevelAlternatives.push({
            start: alternativeStart,
            end: pattern.length
        });

        // 找到组和引用所在的分支
        let groupBranch = -1;
        let refBranch = -1;

        for (let i = 0; i < topLevelAlternatives.length; i++) {
            const alt = topLevelAlternatives[i];
            if (group.startIndex >= alt.start && group.endIndex <= alt.end) {
                groupBranch = i;
            }
            if (refIndex >= alt.start && refIndex <= alt.end) {
                refBranch = i;
            }
        }

        // 如果组和引用在不同的顶层分支中
        if (groupBranch !== -1 && refBranch !== -1 && groupBranch !== refBranch) {
            return true;
        }

        // 检查组内分支
        depth = 0;
        alternativeStart = 0;

        for (let i = 0; i < pattern.length; i++) {
            const char = pattern[i];

            if (char === '(' && !this.isEscaped(pattern, i)) {
                if (pattern.slice(i, i + 3) === '(?:') {
                    i += 2;
                }
                depth++;
                if (depth === 1) {
                    alternativeStart = i + 1;
                }
            } else if (char === ')' && !this.isEscaped(pattern, i)) {
                depth--;
            } else if (char === '|' && !this.isEscaped(pattern, i) && depth === 1) {
                const alternativeEnd = i;
                const isGroupInCurrent = group.startIndex >= alternativeStart &&
                    group.endIndex <= alternativeEnd;
                const isRefInCurrent = refIndex >= alternativeStart &&
                    refIndex <= alternativeEnd;

                if (isGroupInCurrent !== isRefInCurrent) {
                    return true;
                }

                alternativeStart = i + 1;
            }
        }

        return false;
    }

    private isInDifferentOther(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        let depth = 0;
        let alternativeStart = 0;
        let topLevelAlternatives: { start: number; end: number }[] = [];

        // 第一次遍历：收集顶层分支的范围
        for (let i = 0; i < pattern.length; i++) {
            const char = pattern[i];

            if (char === '(' && !this.isEscaped(pattern, i)) {
                depth++;
            } else if (char === ')' && !this.isEscaped(pattern, i)) {
                depth--;
            } else if (char === '|' && !this.isEscaped(pattern, i) && depth === 0) {
                // 记录每个顶层分支的结束位置
                topLevelAlternatives.push({
                    start: alternativeStart,
                    end: i
                });
                alternativeStart = i + 1;
            }
        }
        // 添加最后一个分支
        topLevelAlternatives.push({
            start: alternativeStart,
            end: pattern.length
        });

        // 检查嵌套的分组和分支
        let currentGroup: { start: number; end: number; alternatives: { start: number; end: number }[] } | null = null;
        depth = 0;
        alternativeStart = -1;

        for (let i = 0; i < pattern.length; i++) {
            const char = pattern[i];

            if (char === '(' && !this.isEscaped(pattern, i)) {
                depth++;
                if (alternativeStart === -1) {
                    alternativeStart = i + 1;
                    currentGroup = {
                        start: i,
                        end: -1,
                        alternatives: []
                    };
                }
            } else if (char === ')' && !this.isEscaped(pattern, i)) {
                depth--;
                if (depth === 0 && currentGroup) {
                    currentGroup.end = i;
                    if (alternativeStart !== -1) {
                        currentGroup.alternatives.push({
                            start: alternativeStart,
                            end: i
                        });
                    }
                    // 检查当前分组中的分支情况
                    if (currentGroup.alternatives.length > 0) {
                        let groupContainsRef = false;
                        let groupContainsCapture = false;
                        let refAltIndex = -1;
                        let captureAltIndex = -1;

                        // 检查每个分支
                        for (let j = 0; j < currentGroup.alternatives.length; j++) {
                            const alt = currentGroup.alternatives[j];
                            if (refIndex >= alt.start && refIndex <= alt.end) {
                                groupContainsRef = true;
                                refAltIndex = j;
                            }
                            if (group.startIndex >= alt.start && group.endIndex <= alt.end) {
                                groupContainsCapture = true;
                                captureAltIndex = j;
                            }
                        }

                        // 如果引用和捕获组在不同的分支中
                        if (groupContainsRef && groupContainsCapture && refAltIndex !== captureAltIndex) {
                            return true;
                        }
                    }
                    currentGroup = null;
                    alternativeStart = -1;
                }
            } else if (char === '|' && !this.isEscaped(pattern, i) && currentGroup) {
                currentGroup.alternatives.push({
                    start: alternativeStart,
                    end: i
                });
                alternativeStart = i + 1;
            }
        }

        return false;
    }

    private isInNegativeLookaround(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        // 保留原有的检查逻辑
        const originalResult = this.originalNegativeLookaroundCheck(group, refIndex, pattern);
        if (originalResult) {
            return true;
        }

        let currentIndex = 0;
        while (currentIndex < Math.max(refIndex, group.startIndex)) {
            const lookAroundStart = pattern.indexOf('(?', currentIndex);
            if (lookAroundStart === -1) break;

            // 检查是否是负向环视
            const isNegativeLookbehind = pattern.slice(lookAroundStart, lookAroundStart + 4) === '(?<!';
            const isNegativeLookahead = pattern.slice(lookAroundStart, lookAroundStart + 3) === '(?!';

            if (isNegativeLookahead || isNegativeLookbehind) {
                const { endIndex } = this.findClosingParenthesis(pattern, lookAroundStart);

                // 如果组在负向环视内部
                if (group.startIndex > lookAroundStart && group.endIndex < endIndex) {
                    // 引用也在同一个负向环视内部
                    if (refIndex > lookAroundStart && refIndex < endIndex) {
                        return true;
                    }
                }

                // 如果引用在负向环视内部
                if (refIndex > lookAroundStart && refIndex < endIndex) {
                    // 组在负向环视外部或在其他负向环视内
                    if (group.startIndex < lookAroundStart || group.startIndex > endIndex) {
                        return true;
                    }
                }
            }
            currentIndex = lookAroundStart + 1;
        }
        return false;
    }

    private originalNegativeLookaroundCheck(group: CaptureGroupInfo, refIndex: number, pattern: string): boolean {
        // 匹配所有的负向环视（包括前瞻和后顾）
        const negativeLookarounds = Array.from(pattern.matchAll(/\(\?[<]?!/g));

        for (const lookaround of negativeLookarounds) {
            const start = lookaround.index!;
            const { endIndex } = this.findClosingParenthesis(pattern, start);

            // 情况1：组在负向环视内，引用在外部
            if (group.startIndex > start && group.endIndex < endIndex) {
                // 如果引用在负向环视外部
                if (refIndex >= endIndex) {
                    return true;
                }
            }

            // 情况2：引用在负向环视内，但引用了外部的组
            if (refIndex > start && refIndex < endIndex) {
                if (!(group.startIndex > start && group.endIndex < endIndex)) {
                    return true;
                }
            }

            // 情况3：检查嵌套的负向环视
            const subPattern = pattern.slice(start, endIndex);
            if (this.hasNestedNegativeLookaround(subPattern, group, refIndex - start)) {
                return true;
            }
        }

        return false;
    }

    private hasNestedNegativeLookaround(pattern: string, group: CaptureGroupInfo, relativeRefIndex: number): boolean {
        const nestedNegative = Array.from(pattern.matchAll(/\(\?[<]?!/g));

        for (const nested of nestedNegative) {
            if (nested.index === 0) continue; // 跳过当前环视本身

            const nestedStart = nested.index!;
            const { endIndex: nestedEnd } = this.findClosingParenthesis(pattern, nestedStart);

            // 检查组是否在嵌套的负向环视内
            const relativeGroupStart = group.startIndex - (group.startIndex > nestedStart ? nestedStart : 0);
            const relativeGroupEnd = group.endIndex - (group.endIndex > nestedStart ? nestedStart : 0);

            if (relativeGroupStart > nestedStart && relativeGroupEnd < nestedEnd) {
                // 如果引用在嵌套的负向环视外部
                if (relativeRefIndex < nestedStart || relativeRefIndex >= nestedEnd) {
                    return true;
                }
            }
        }

        return false;
    }

    private reportIssue(node: ts.Node, sourceFile: ts.SourceFile, group: CaptureGroupInfo, backRef: string, refIndex: number): void {
        this.backReferenceInfo = {
            backReference: backRef,
            groupContent: group.content
        };

        const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());

        const commentInfo: CommentInfo = {
            line: line + 1,
            startCol: character + 1,
            message: this.messages[this.messageId],
            filePath: this.filePath
        };

        // 使用唯一键来避免重复报告
        const defect = this.addIssueReport(commentInfo);
        const issue = new IssueReport(defect, undefined);
        this.issueMap.set(defect.fixKey, issue);
    }

    private addIssueReport(commentInfo: CommentInfo): Defects {
        this.metaData.description = commentInfo.message;
        const severity = this.rule.alert ?? this.metaData.severity;
        const fixKey = commentInfo.line + '%' + commentInfo.startCol + '%' + this.rule.ruleId + '%' + Date.now() + Math.random();
        const mergeKey = commentInfo.filePath + '%' + fixKey + '%' + this.metaData.description;
        const defect = new Defects(commentInfo.line, commentInfo.startCol, this.metaData.description, severity,
            this.rule.ruleId, mergeKey, this.metaData.ruleDocPath, true, false, false, fixKey);
        this.defects.push(defect);
        return defect;
    }

    private reportSortedIssues(): void {
        if (this.issueMap.size === 0) {
            return;
        }

        const sortedIssues = Array.from(this.issueMap.entries())
            .sort(([keyA], [keyB]) => Utils.sortByLineAndColumn(keyA, keyB));

        this.issues = [];

        sortedIssues.forEach(([_, issue]) => {
            RuleListUtil.push(issue.defect);
            this.issues.push(issue);
        });
    }
}
